Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Displaying Raw • Download


meshchatx/src/backend/audio_codec.py e5756d7ab065475a18acdcafc008a767fcff87e0 (e5756d7a) Text, 11.77 KB

T8b949e# SPDX-License-Identifier: 0BSD
T8b949e"""Pure-Python audio decode/encode helpers used across MeshChatX.

This module replaces the previous ffmpeg subprocess pipelines used for
voicemail greetings, ringtones and browser-recorded voice messages. It
exposes a small API that decodes user-supplied audio into float32 PCM
frames and encodes PCM frames into LXMF-compatible OGG/Opus files using
LXST.Sinks.OpusFileSink.

Decoders, in priority order:

1. wave (built-in) for RIFF/WAVE containers.
2. miniaudio (https://pypi.org/project/miniaudio/) for WAV, MP3, FLAC
and OGG/Vorbis. Bundled as a runtime dependency on every supported
target (including Android via the Chaquopy recipe under
android/chaquopy-recipes/miniaudio-1.70).
3. LXST/pyogg OpusFile for OGG/Opus payloads.

Encoder: LXST.Sinks.OpusFileSink configured with a voice-friendly
Opus profile so the output is a valid OGG/Opus file that Sideband and
the rest of the LXMF ecosystem can play.
"""

Tff7b72from T7ee787__future__ Tff7b72import Te6edf3annotations

Tff7b72import T7ee787io
Tff7b72import T7ee787os
Tff7b72import T7ee787tempfile
Tff7b72import T7ee787wave
Tff7b72from T7ee787dataclasses Tff7b72import Te6edf3dataclass


Tf0883e@dataclassTb4b4b4(Te6edf3frozenTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72class T56d364DecodedAudioTb4b4b4:
T8b949e"""A decoded audio buffer.

Attributes:
samples: float32 numpy array shaped (frames, channels) with
values in [-1.0, 1.0].
samplerate: PCM sample rate in Hz.
channels: Channel count.

"""

Te6edf3samplesTb4b4b4: Tffa657object
Te6edf3samplerateTb4b4b4: Tffa657int
Te6edf3channelsTb4b4b4: Tffa657int


Tff7b72def Td2a8ff_read_bytesTb4b4b4(Te6edf3sourceTb4b4b4) Tff7b72-Tff7b72> Tffa657bytesTb4b4b4:
T8b949e"""Return the bytes for source (path, file-like or bytes)."""
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3sourceTb4b4b4, Tb4b4b4(Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4, Tffa657memoryviewTb4b4b4)Tb4b4b4)Tb4b4b4:
Tff7b72return Tffa657bytesTb4b4b4(Te6edf3sourceTb4b4b4)
Tff7b72if Tffa657hasattrTb4b4b4(Te6edf3sourceTb4b4b4, Ta5d6ff"Ta5d6ffreadTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3data Tff7b72= Te6edf3sourceTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3data Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3dataTb4b4b4, Tffa657bytesTb4b4b4) Tff7b72else Tffa657bytesTb4b4b4(Te6edf3dataTb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3sourceTb4b4b4, Tb4b4b4(Tffa657strTb4b4b4, Te6edf3osTff7b72.Td2a8ffPathLikeTb4b4b4)Tb4b4b4)Tb4b4b4:
Tff7b72with Tffa657openTb4b4b4(Te6edf3osTff7b72.Td2a8fffspathTb4b4b4(Te6edf3sourceTb4b4b4)Tb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Tff7b72return Te6edf3fTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)
Te6edf3msg Tff7b72= Ta5d6fffTa5d6ff"Ta5d6ffUnsupported audio source type: Tffd700{Tffa657typeTb4b4b4(Te6edf3sourceTb4b4b4)Tffd700!r}Ta5d6ff"
Tff7b72raise Tf85149TypeErrorTb4b4b4(Te6edf3msgTb4b4b4)


Tff7b72def Td2a8ff_decode_with_waveTb4b4b4(Te6edf3dataTb4b4b4: Tffa657bytesTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4) Tff7b72< T79c0ff12 Tff7b72or Te6edf3dataTb4b4b4[Tb4b4b4:T79c0ff4Tb4b4b4] Tff7b72!= Ta5d6ffbTa5d6ff"Ta5d6ffRIFFTa5d6ff" Tff7b72or Te6edf3dataTb4b4b4[T79c0ff8Tb4b4b4:T79c0ff12Tb4b4b4] Tff7b72!= Ta5d6ffbTa5d6ff"Ta5d6ffWAVETa5d6ff"Tb4b4b4:
Tff7b72return Tff7b72None
Tff7b72tryTb4b4b4:
Tff7b72import T7ee787numpy Tff7b72as T7ee787np

Tff7b72with Te6edf3waveTff7b72.Td2a8ffopenTb4b4b4(Te6edf3ioTff7b72.Td2a8ffBytesIOTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3wfTb4b4b4:
Te6edf3channels Tff7b72= Te6edf3wfTff7b72.Td2a8ffgetnchannelsTb4b4b4(Tb4b4b4)
Te6edf3sample_width Tff7b72= Te6edf3wfTff7b72.Td2a8ffgetsampwidthTb4b4b4(Tb4b4b4)
Te6edf3framerate Tff7b72= Te6edf3wfTff7b72.Td2a8ffgetframerateTb4b4b4(Tb4b4b4)
Te6edf3raw Tff7b72= Te6edf3wfTff7b72.Td2a8ffreadframesTb4b4b4(Te6edf3wfTff7b72.Td2a8ffgetnframesTb4b4b4(Tb4b4b4)Tb4b4b4)

Tff7b72if Te6edf3channels Tff7b72< T79c0ff1 Tff7b72or Te6edf3framerate Tff7b72<Tff7b72= T79c0ff0 Tff7b72or Tffa657lenTb4b4b4(Te6edf3rawTb4b4b4) Tff7b72== T79c0ff0Tb4b4b4:
Tff7b72return Tff7b72None

Tff7b72if Te6edf3sample_width Tff7b72== T79c0ff2Tb4b4b4:
Te6edf3samples Tff7b72= Te6edf3npTff7b72.Td2a8fffrombufferTb4b4b4(Te6edf3rawTb4b4b4, Te6edf3dtypeTff7b72=Te6edf3npTff7b72.Td2a8ffint16Tb4b4b4)Tff7b72.Td2a8ffastypeTb4b4b4(Te6edf3npTff7b72.Td2a8fffloat32Tb4b4b4) Tff7b72/ T79c0ff32768.0
Tff7b72elif Te6edf3sample_width Tff7b72== T79c0ff1Tb4b4b4:
Te6edf3samples Tff7b72= Tb4b4b4(
Te6edf3npTff7b72.Td2a8fffrombufferTb4b4b4(Te6edf3rawTb4b4b4, Te6edf3dtypeTff7b72=Te6edf3npTff7b72.Td2a8ffuint8Tb4b4b4)Tff7b72.Td2a8ffastypeTb4b4b4(Te6edf3npTff7b72.Td2a8fffloat32Tb4b4b4) Tff7b72- T79c0ff128.0
Tb4b4b4) Tff7b72/ T79c0ff128.0
Tff7b72elif Te6edf3sample_width Tff7b72== T79c0ff4Tb4b4b4:
Te6edf3samples Tff7b72= Tb4b4b4(
Te6edf3npTff7b72.Td2a8fffrombufferTb4b4b4(Te6edf3rawTb4b4b4, Te6edf3dtypeTff7b72=Te6edf3npTff7b72.Td2a8ffint32Tb4b4b4)Tff7b72.Td2a8ffastypeTb4b4b4(Te6edf3npTff7b72.Td2a8fffloat32Tb4b4b4) Tff7b72/ T79c0ff2147483648.0
Tb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72return Tff7b72None

Tff7b72return Te6edf3DecodedAudioTb4b4b4(
Te6edf3samplesTff7b72=Te6edf3samplesTff7b72.Td2a8ffreshapeTb4b4b4(Tff7b72-T79c0ff1Tb4b4b4, Te6edf3channelsTb4b4b4)Tb4b4b4,
Te6edf3samplerateTff7b72=Te6edf3framerateTb4b4b4,
Te6edf3channelsTff7b72=Te6edf3channelsTb4b4b4,
Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72return Tff7b72None


Tff7b72def Td2a8ff_decode_with_miniaudioTb4b4b4(Te6edf3dataTb4b4b4: Tffa657bytesTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72import T7ee787miniaudio
Tff7b72import T7ee787numpy Tff7b72as T7ee787np
Tff7b72except Tf85149ImportErrorTb4b4b4:
Tff7b72return Tff7b72None
Tff7b72tryTb4b4b4:
Te6edf3decoded Tff7b72= Te6edf3miniaudioTff7b72.Td2a8ffdecodeTb4b4b4(
Te6edf3dataTb4b4b4,
Te6edf3output_formatTff7b72=Te6edf3miniaudioTff7b72.Td2a8ffSampleFormatTff7b72.Td2a8ffSIGNED16Tb4b4b4,
Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72return Tff7b72None
Tff7b72if Te6edf3decodedTff7b72.Td2a8ffnum_frames Tff7b72<Tff7b72= T79c0ff0 Tff7b72or Te6edf3decodedTff7b72.Td2a8ffnchannels Tff7b72<Tff7b72= T79c0ff0Tb4b4b4:
Tff7b72return Tff7b72None
Te6edf3samples Tff7b72= Tb4b4b4(
Te6edf3npTff7b72.Td2a8fffrombufferTb4b4b4(Te6edf3decodedTff7b72.Td2a8ffsamplesTb4b4b4, Te6edf3dtypeTff7b72=Te6edf3npTff7b72.Td2a8ffint16Tb4b4b4)Tff7b72.Td2a8ffastypeTb4b4b4(Te6edf3npTff7b72.Td2a8fffloat32Tb4b4b4) Tff7b72/ T79c0ff32768.0
Tb4b4b4)
Tff7b72return Te6edf3DecodedAudioTb4b4b4(
Te6edf3samplesTff7b72=Te6edf3samplesTff7b72.Td2a8ffreshapeTb4b4b4(Tff7b72-T79c0ff1Tb4b4b4, Te6edf3decodedTff7b72.Td2a8ffnchannelsTb4b4b4)Tb4b4b4,
Te6edf3samplerateTff7b72=Te6edf3decodedTff7b72.Td2a8ffsample_rateTb4b4b4,
Te6edf3channelsTff7b72=Te6edf3decodedTff7b72.Td2a8ffnchannelsTb4b4b4,
Tb4b4b4)


Tff7b72def Td2a8ff_decode_with_lxst_opusTb4b4b4(Te6edf3dataTb4b4b4: Tffa657bytesTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3dataTb4b4b4[Tb4b4b4:T79c0ff4Tb4b4b4] Tff7b72!= Ta5d6ffbTa5d6ff"Ta5d6ffOggSTa5d6ff"Tb4b4b4:
Tff7b72return Tff7b72None
Tff7b72tryTb4b4b4:
Tff7b72import T7ee787numpy Tff7b72as T7ee787np
Tff7b72from T7ee787LXSTT7ee787.T7ee787CodecsT7ee787.T7ee787libsT7ee787.T7ee787pyogg Tff7b72import Te6edf3OpusFile
Tff7b72except Tf85149ImportErrorTb4b4b4:
Tff7b72return Tff7b72None
Te6edf3tmp Tff7b72= Te6edf3tempfileTff7b72.Td2a8ffNamedTemporaryFileTb4b4b4(Te6edf3suffixTff7b72=Ta5d6ff"Ta5d6ff.opusTa5d6ff"Tb4b4b4, Te6edf3deleteTff7b72=Tff7b72FalseTb4b4b4)
Te6edf3tmpTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Tff7b72tryTb4b4b4:
Tff7b72with Tffa657openTb4b4b4(Te6edf3tmpTff7b72.Td2a8ffnameTb4b4b4, Ta5d6ff"Ta5d6ffwbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Te6edf3fTff7b72.Td2a8ffwriteTb4b4b4(Te6edf3dataTb4b4b4)
Te6edf3opus Tff7b72= Te6edf3OpusFileTb4b4b4(Te6edf3tmpTff7b72.Td2a8ffnameTb4b4b4)
Te6edf3type_max Tff7b72= Tffa657floatTb4b4b4(Te6edf3npTff7b72.Td2a8ffiinfoTb4b4b4(Te6edf3npTff7b72.Td2a8ffint16Tb4b4b4)Tff7b72.Td2a8ffmaxTb4b4b4)
Te6edf3samples Tff7b72= Te6edf3opusTff7b72.Td2a8ffas_arrayTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffastypeTb4b4b4(Te6edf3npTff7b72.Td2a8fffloat32Tb4b4b4) Tff7b72/ Te6edf3type_max
Tff7b72if Te6edf3samplesTff7b72.Td2a8ffndim Tff7b72== T79c0ff1Tb4b4b4:
Te6edf3samples Tff7b72= Te6edf3samplesTff7b72.Td2a8ffreshapeTb4b4b4(Tff7b72-T79c0ff1Tb4b4b4, Te6edf3opusTff7b72.Td2a8ffchannelsTb4b4b4)
Tff7b72return Te6edf3DecodedAudioTb4b4b4(
Te6edf3samplesTff7b72=Te6edf3samplesTb4b4b4,
Te6edf3samplerateTff7b72=Tffa657intTb4b4b4(Te6edf3opusTff7b72.Td2a8fffrequencyTb4b4b4)Tb4b4b4,
Te6edf3channelsTff7b72=Tffa657intTb4b4b4(Te6edf3opusTff7b72.Td2a8ffchannelsTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72return Tff7b72None
Tff7b72finallyTb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3osTff7b72.Td2a8ffunlinkTb4b4b4(Te6edf3tmpTff7b72.Td2a8ffnameTb4b4b4)
Tff7b72except Tf85149OSErrorTb4b4b4:
Tff7b72pass


Tff7b72def Td2a8ffdecode_audioTb4b4b4(Te6edf3sourceTb4b4b4) Tff7b72-Tff7b72> Te6edf3DecodedAudioTb4b4b4:
T8b949e"""Decode source into float32 PCM frames.

source may be a path (str/os.PathLike), a file-like object
open in binary mode, or a bytes/bytearray payload.

Raises:
ValueError: If the payload could not be decoded by any backend.

"""
Te6edf3data Tff7b72= Te6edf3_read_bytesTb4b4b4(Te6edf3sourceTb4b4b4)
Tff7b72for Te6edf3decoder Tff7b72in Tb4b4b4(Te6edf3_decode_with_waveTb4b4b4, Te6edf3_decode_with_miniaudioTb4b4b4, Te6edf3_decode_with_lxst_opusTb4b4b4)Tb4b4b4:
Te6edf3result Tff7b72= Te6edf3decoderTb4b4b4(Te6edf3dataTb4b4b4)
Tff7b72if Te6edf3result Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3result
Te6edf3msg Tff7b72= Ta5d6ff"Ta5d6ffUnsupported audio format (could not decode with wave/miniaudio/LXST)Ta5d6ff"
Tff7b72raise Tf85149ValueErrorTb4b4b4(Te6edf3msgTb4b4b4)


Tff7b72def Td2a8ff_opus_voice_profileTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72from T7ee787LXSTT7ee787.T7ee787Codecs Tff7b72import Te6edf3Opus

Tff7b72return Te6edf3OpusTff7b72.Td2a8ffPROFILE_VOICE_HIGH


Te6edf3_OPUS_VALID_RATES Tff7b72= Tb4b4b4(T79c0ff8000Tb4b4b4, T79c0ff12000Tb4b4b4, T79c0ff16000Tb4b4b4, T79c0ff24000Tb4b4b4, T79c0ff48000Tb4b4b4)
Te6edf3_OPUS_TARGET_RATE Tff7b72= T79c0ff48000


Tff7b72def Td2a8ff_normalize_for_opusTb4b4b4(
Te6edf3samplesTb4b4b4,
Te6edf3samplerateTb4b4b4: Tffa657intTb4b4b4,
Te6edf3channelsTb4b4b4: Tffa657intTb4b4b4,
Te6edf3target_rateTb4b4b4: Tffa657int Tff7b72= Te6edf3_OPUS_TARGET_RATETb4b4b4,
Te6edf3target_channelsTb4b4b4: Tffa657int Tff7b72= T79c0ff1Tb4b4b4,
Tb4b4b4)Tb4b4b4:
T8b949e"""Resample/remix samples to a layout the chosen Opus profile accepts.

Returns float32 frames at target_rate with target_channels
channels. Multi-channel input is downmixed to mono by averaging,
mono input is duplicated when the profile expects stereo, and the
rate is resampled via LXST's helper to stay consistent with the
rest of the pipeline.
"""
Tff7b72import T7ee787numpy Tff7b72as T7ee787np

Tff7b72if Te6edf3samplesTff7b72.Td2a8ffndim Tff7b72== T79c0ff1Tb4b4b4:
Te6edf3samples Tff7b72= Te6edf3samplesTff7b72.Td2a8ffreshapeTb4b4b4(Tff7b72-T79c0ff1Tb4b4b4, Tffa657maxTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3channelsTb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3samplesTff7b72.Td2a8ffdtype Tff7b72!= Te6edf3npTff7b72.Td2a8fffloat32Tb4b4b4:
Te6edf3samples Tff7b72= Te6edf3samplesTff7b72.Td2a8ffastypeTb4b4b4(Te6edf3npTff7b72.Td2a8fffloat32Tb4b4b4)

Te6edf3target_channels Tff7b72= Tffa657maxTb4b4b4(T79c0ff1Tb4b4b4, Tffa657intTb4b4b4(Te6edf3target_channelsTb4b4b4)Tb4b4b4)
Te6edf3in_channels Tff7b72= Te6edf3samplesTff7b72.Td2a8ffshapeTb4b4b4[T79c0ff1Tb4b4b4]
Tff7b72if Te6edf3in_channels Tff7b72!= Te6edf3target_channelsTb4b4b4:
Tff7b72if Te6edf3target_channels Tff7b72== T79c0ff1Tb4b4b4:
Te6edf3samples Tff7b72= Te6edf3samplesTff7b72.Td2a8ffmeanTb4b4b4(Te6edf3axisTff7b72=T79c0ff1Tb4b4b4, Te6edf3keepdimsTff7b72=Tff7b72TrueTb4b4b4)Tff7b72.Td2a8ffastypeTb4b4b4(Te6edf3npTff7b72.Td2a8fffloat32Tb4b4b4)
Tff7b72elif Te6edf3in_channels Tff7b72== T79c0ff1Tb4b4b4:
Te6edf3samples Tff7b72= Te6edf3npTff7b72.Td2a8ffrepeatTb4b4b4(Te6edf3samplesTb4b4b4, Te6edf3target_channelsTb4b4b4, Te6edf3axisTff7b72=T79c0ff1Tb4b4b4)
Tff7b72elif Te6edf3in_channels Tff7b72> Te6edf3target_channelsTb4b4b4:
Te6edf3samples Tff7b72= Te6edf3samplesTb4b4b4[Tb4b4b4:Tb4b4b4, Tb4b4b4:Te6edf3target_channelsTb4b4b4]
Tff7b72elseTb4b4b4:
Te6edf3pad Tff7b72= Te6edf3npTff7b72.Td2a8ffrepeatTb4b4b4(Te6edf3samplesTb4b4b4[Tb4b4b4:Tb4b4b4, Tff7b72-T79c0ff1Tb4b4b4:Tb4b4b4]Tb4b4b4, Te6edf3target_channels Tff7b72- Te6edf3in_channelsTb4b4b4, Te6edf3axisTff7b72=T79c0ff1Tb4b4b4)
Te6edf3samples Tff7b72= Te6edf3npTff7b72.Td2a8ffhstackTb4b4b4(Tb4b4b4[Te6edf3samplesTb4b4b4, Te6edf3padTb4b4b4]Tb4b4b4)
Te6edf3channels Tff7b72= Te6edf3target_channels

Tff7b72if Tffa657intTb4b4b4(Te6edf3samplerateTb4b4b4) Tff7b72!= Tffa657intTb4b4b4(Te6edf3target_rateTb4b4b4)Tb4b4b4:
Tff7b72from T7ee787LXSTT7ee787.T7ee787CodecsT7ee787.T7ee787Codec Tff7b72import Te6edf3resample

Te6edf3samples Tff7b72= Te6edf3resampleTb4b4b4(
Te6edf3samplesTb4b4b4,
T79c0ff16Tb4b4b4,
Te6edf3channelsTb4b4b4,
Tffa657intTb4b4b4(Te6edf3samplerateTb4b4b4)Tb4b4b4,
Tffa657intTb4b4b4(Te6edf3target_rateTb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3samplerate Tff7b72= Tffa657intTb4b4b4(Te6edf3target_rateTb4b4b4)

Tff7b72return Te6edf3samplesTb4b4b4, Te6edf3samplerateTb4b4b4, Te6edf3channels


Tff7b72def Td2a8ffencode_pcm_to_ogg_opusTb4b4b4(
Te6edf3samplesTb4b4b4,
Te6edf3samplerateTb4b4b4: Tffa657intTb4b4b4,
Te6edf3channelsTb4b4b4: Tffa657intTb4b4b4,
Te6edf3output_pathTb4b4b4: Tffa657strTb4b4b4,
Te6edf3profileTff7b72=Tff7b72NoneTb4b4b4,
Te6edf3frame_msTb4b4b4: Tffa657int Tff7b72= T79c0ff60Tb4b4b4,
Tb4b4b4) Tff7b72-Tff7b72> Tffa657strTb4b4b4:
T8b949e"""Encode samples (float32 (frames, channels)) to OGG/Opus.

profile defaults to LXST.Codecs.Opus.PROFILE_VOICE_HIGH (48 kHz
mono voip, ~16 kbps ceiling) which keeps voice payloads small while
remaining intelligible. Inputs at any sample rate or channel count are
transparently resampled/remixed to the profile's expected layout
before encoding.

Encoding is fully synchronous: PCM is fed straight into a
OpusBufferedEncoder wrapped by an OggOpusWriter and flushed
on close, so the encoded duration matches the input exactly with no
frame loss and no trailing silence padding.
"""
Tff7b72import T7ee787numpy Tff7b72as T7ee787np
Tff7b72from T7ee787LXSTT7ee787.T7ee787Codecs Tff7b72import Te6edf3Opus
Tff7b72from T7ee787LXSTT7ee787.T7ee787CodecsT7ee787.T7ee787libsT7ee787.T7ee787pyogg Tff7b72import Te6edf3OggOpusWriterTb4b4b4, Te6edf3OpusBufferedEncoder

Tff7b72if Te6edf3profile Tff7b72is Tff7b72NoneTb4b4b4:
Te6edf3profile Tff7b72= Te6edf3_opus_voice_profileTb4b4b4(Tb4b4b4)

Te6edf3target_rate Tff7b72= Tffa657intTb4b4b4(Te6edf3OpusTff7b72.Td2a8ffprofile_samplerateTb4b4b4(Te6edf3profileTb4b4b4)Tb4b4b4)
Te6edf3target_channels Tff7b72= Te6edf3OpusTff7b72.Td2a8ffprofile_channelsTb4b4b4(Te6edf3profileTb4b4b4)
Tff7b72if Tff7b72not Te6edf3target_channelsTb4b4b4:
Te6edf3target_channels Tff7b72= Tffa657maxTb4b4b4(T79c0ff1Tb4b4b4, Tffa657intTb4b4b4(Te6edf3channelsTb4b4b4)Tb4b4b4)
Te6edf3application Tff7b72= Te6edf3OpusTff7b72.Td2a8ffprofile_applicationTb4b4b4(Te6edf3profileTb4b4b4)
Te6edf3bitrate_ceiling Tff7b72= Te6edf3OpusTff7b72.Td2a8ffprofile_bitrate_ceilingTb4b4b4(Te6edf3profileTb4b4b4)

Te6edf3samplesTb4b4b4, Te6edf3samplerateTb4b4b4, Te6edf3channels Tff7b72= Te6edf3_normalize_for_opusTb4b4b4(
Te6edf3samplesTb4b4b4,
Te6edf3samplerateTb4b4b4,
Te6edf3channelsTb4b4b4,
Te6edf3target_rateTff7b72=Te6edf3target_rateTb4b4b4,
Te6edf3target_channelsTff7b72=Te6edf3target_channelsTb4b4b4,
Tb4b4b4)

Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffexistsTb4b4b4(Te6edf3output_pathTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3output_pathTb4b4b4)

Te6edf3encoder Tff7b72= Te6edf3OpusBufferedEncoderTb4b4b4(Tb4b4b4)
Te6edf3encoderTff7b72.Td2a8ffset_applicationTb4b4b4(Te6edf3applicationTb4b4b4)
Te6edf3encoderTff7b72.Td2a8ffset_sampling_frequencyTb4b4b4(Tffa657intTb4b4b4(Te6edf3samplerateTb4b4b4)Tb4b4b4)
Te6edf3encoderTff7b72.Td2a8ffset_channelsTb4b4b4(Tffa657intTb4b4b4(Te6edf3channelsTb4b4b4)Tb4b4b4)
Te6edf3encoderTff7b72.Td2a8ffset_frame_sizeTb4b4b4(Tffa657intTb4b4b4(Te6edf3frame_msTb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3bitrate_ceilingTb4b4b4:
Te6edf3encoderTff7b72.Td2a8ffset_max_bytes_per_frameTb4b4b4(
Te6edf3OpusTff7b72.Td2a8ffmax_bytes_per_frameTb4b4b4(Te6edf3bitrate_ceilingTb4b4b4, Te6edf3frame_msTb4b4b4)Tb4b4b4,
Tb4b4b4)

Te6edf3type_max Tff7b72= Te6edf3npTff7b72.Td2a8ffiinfoTb4b4b4(Te6edf3npTff7b72.Td2a8ffint16Tb4b4b4)Tff7b72.Td2a8ffmax
Te6edf3samples_per_frame Tff7b72= Tffa657maxTb4b4b4(T79c0ff1Tb4b4b4, Tffa657intTb4b4b4(Te6edf3samplerate Tff7b72* Te6edf3frame_ms Tff7b72/ T79c0ff1000Tb4b4b4)Tb4b4b4)

Te6edf3writer Tff7b72= Te6edf3OggOpusWriterTb4b4b4(Te6edf3output_pathTb4b4b4, Te6edf3encoderTb4b4b4)
Tff7b72tryTb4b4b4:
Tff7b72if Te6edf3samplesTff7b72.Td2a8ffshapeTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72== T79c0ff0Tb4b4b4:
Te6edf3silence Tff7b72= Te6edf3npTff7b72.Td2a8ffzerosTb4b4b4(Tb4b4b4(Te6edf3samples_per_frameTb4b4b4, Te6edf3channelsTb4b4b4)Tb4b4b4, Te6edf3dtypeTff7b72=Te6edf3npTff7b72.Td2a8ffint16Tb4b4b4)
Te6edf3writerTff7b72.Td2a8ffwriteTb4b4b4(Tffa657memoryviewTb4b4b4(Tffa657bytearrayTb4b4b4(Te6edf3silenceTff7b72.Td2a8fftobytesTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3clipped Tff7b72= Te6edf3npTff7b72.Td2a8ffclipTb4b4b4(Te6edf3samplesTb4b4b4, Tff7b72-T79c0ff1.0Tb4b4b4, T79c0ff1.0Tb4b4b4) Tff7b72* Te6edf3type_max
Te6edf3int_samples Tff7b72= Te6edf3clippedTff7b72.Td2a8ffastypeTb4b4b4(Te6edf3npTff7b72.Td2a8ffint16Tb4b4b4)
Te6edf3writerTff7b72.Td2a8ffwriteTb4b4b4(Tffa657memoryviewTb4b4b4(Tffa657bytearrayTb4b4b4(Te6edf3int_samplesTff7b72.Td2a8fftobytesTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4)
Tff7b72finallyTb4b4b4:
Te6edf3writerTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3output_path


Tff7b72def Td2a8ffencode_audio_to_ogg_opusTb4b4b4(Te6edf3sourceTb4b4b4, Te6edf3output_pathTb4b4b4: Tffa657strTb4b4b4, Te6edf3profileTff7b72=Tff7b72NoneTb4b4b4) Tff7b72-Tff7b72> Tffa657strTb4b4b4:
T8b949e"""Decode any supported source and re-encode it as OGG/Opus.

Intended for converting user-uploaded greetings/ringtones (any format
miniaudio can decode) into the OGG/Opus container required by the
rest of the stack.
"""
Te6edf3decoded Tff7b72= Te6edf3decode_audioTb4b4b4(Te6edf3sourceTb4b4b4)
Tff7b72return Te6edf3encode_pcm_to_ogg_opusTb4b4b4(
Te6edf3decodedTff7b72.Td2a8ffsamplesTb4b4b4,
Te6edf3decodedTff7b72.Td2a8ffsamplerateTb4b4b4,
Te6edf3decodedTff7b72.Td2a8ffchannelsTb4b4b4,
Te6edf3output_pathTb4b4b4,
Te6edf3profileTff7b72=Te6edf3profileTb4b4b4,
Tb4b4b4)


Tff7b72def Td2a8ffwrite_silence_ogg_opusTb4b4b4(
Te6edf3output_pathTb4b4b4: Tffa657strTb4b4b4,
Te6edf3secondsTb4b4b4: Tffa657float Tff7b72= T79c0ff1.0Tb4b4b4,
Te6edf3samplerateTb4b4b4: Tffa657int Tff7b72= T79c0ff48000Tb4b4b4,
Te6edf3channelsTb4b4b4: Tffa657int Tff7b72= T79c0ff1Tb4b4b4,
Te6edf3profileTff7b72=Tff7b72NoneTb4b4b4,
Tb4b4b4) Tff7b72-Tff7b72> Tffa657strTb4b4b4:
T8b949e"""Write a silent OGG/Opus file of seconds seconds to output_path."""
Tff7b72import T7ee787numpy Tff7b72as T7ee787np

Te6edf3duration Tff7b72= Tffa657maxTb4b4b4(T79c0ff0.05Tb4b4b4, Tffa657floatTb4b4b4(Te6edf3secondsTb4b4b4)Tb4b4b4)
Te6edf3n_frames Tff7b72= Tffa657intTb4b4b4(Te6edf3samplerate Tff7b72* Te6edf3durationTb4b4b4)
Te6edf3silence Tff7b72= Te6edf3npTff7b72.Td2a8ffzerosTb4b4b4(Tb4b4b4(Te6edf3n_framesTb4b4b4, Tffa657maxTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3channelsTb4b4b4)Tb4b4b4)Tb4b4b4, Te6edf3dtypeTff7b72=Te6edf3npTff7b72.Td2a8fffloat32Tb4b4b4)
Tff7b72return Te6edf3encode_pcm_to_ogg_opusTb4b4b4(
Te6edf3silenceTb4b4b4,
Te6edf3samplerateTb4b4b4,
Te6edf3channelsTb4b4b4,
Te6edf3output_pathTb4b4b4,
Te6edf3profileTff7b72=Te6edf3profileTb4b4b4,
Tb4b4b4)


Tff7b72def Td2a8ffis_ogg_opus_bytesTb4b4b4(Te6edf3dataTb4b4b4: Tffa657bytesTb4b4b4) Tff7b72-Tff7b72> Tffa657boolTb4b4b4:
T8b949e"""Return True if data looks like an OGG container payload."""
Tff7b72return Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4) Tff7b72>Tff7b72= T79c0ff4 Tff7b72and Te6edf3dataTb4b4b4[Tb4b4b4:T79c0ff4Tb4b4b4] Tff7b72== Ta5d6ffbTa5d6ff"Ta5d6ffOggSTa5d6ff"


Tff7b72def Td2a8ffencode_audio_bytes_to_ogg_opusTb4b4b4(Te6edf3dataTb4b4b4: Tffa657bytesTb4b4b4, Te6edf3profileTff7b72=Tff7b72NoneTb4b4b4) Tff7b72-Tff7b72> Tffa657bytes Tff7b72| Tff7b72NoneTb4b4b4:
T8b949e"""Decode data and return the corresponding OGG/Opus byte string.

Returns None if the payload could not be decoded. If the payload
is already an OGG container it is returned unchanged.
"""
Tff7b72if Te6edf3is_ogg_opus_bytesTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3data
Tff7b72tryTb4b4b4:
Te6edf3decoded Tff7b72= Te6edf3decode_audioTb4b4b4(Te6edf3dataTb4b4b4)
Tff7b72except Tb4b4b4(Tf85149TypeErrorTb4b4b4, Tf85149ValueErrorTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72None
Te6edf3tmp Tff7b72= Te6edf3tempfileTff7b72.Td2a8ffNamedTemporaryFileTb4b4b4(Te6edf3suffixTff7b72=Ta5d6ff"Ta5d6ff.opusTa5d6ff"Tb4b4b4, Te6edf3deleteTff7b72=Tff7b72FalseTb4b4b4)
Te6edf3tmpTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3encode_pcm_to_ogg_opusTb4b4b4(
Te6edf3decodedTff7b72.Td2a8ffsamplesTb4b4b4,
Te6edf3decodedTff7b72.Td2a8ffsamplerateTb4b4b4,
Te6edf3decodedTff7b72.Td2a8ffchannelsTb4b4b4,
Te6edf3tmpTff7b72.Td2a8ffnameTb4b4b4,
Te6edf3profileTff7b72=Te6edf3profileTb4b4b4,
Tb4b4b4)
Tff7b72with Tffa657openTb4b4b4(Te6edf3tmpTff7b72.Td2a8ffnameTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Tff7b72return Te6edf3fTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72return Tff7b72None
Tff7b72finallyTb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3osTff7b72.Td2a8ffunlinkTb4b4b4(Te6edf3tmpTff7b72.Td2a8ffnameTb4b4b4)
Tff7b72except Tf85149OSErrorTb4b4b4:
Tff7b72pass


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────